//
//  SmartLinkExportObject.m
//  SmartLink
//
//  Created by gicisky on 16/3/2.
//  Copyright © 2016年 gicisky. All rights reserved.
//

#import "SmartLinkExportObject.h"
#import "JMAirKissEncoder.h"
#import "MyAirKissGCDAsyncUdpSocket.h"


#import <SystemConfiguration/SystemConfiguration.h>
#import <SystemConfiguration/CaptiveNetwork.h>

#include <inttypes.h>


#define CRC8INIT 0x00
#define CRC8POLY 0x31 // = X^8+X^5+X^4+X^0

#define kAirKiss_Port                    10000
#define kAirKiss_Host                    @"255.255.255.255"
#define kAirKiss_Limit_Return_Random_Num 5

@interface SmartLinkExportObject()<MyAirKissGCDAsyncUdpSocketDelegate>
{
    JMAirKissEncoder  *_airKissEncoder;
    NSTimer           *_timer;          // 超过1分钟未连接成功则表示失败
    MyAirKissGCDAsyncUdpSocket *_clientUdpSocket;
    MyAirKissGCDAsyncUdpSocket *_serverUdpSocket;
    
    NSMutableArray *dataArray;
    long              _tag;
    int               _returnRandomNum;
    BOOL              _connectionDone;
}
@end

@implementation SmartLinkExportObject

- (instancetype)init
{
    self = [super init];
    if (self) {
        _airKissEncoder  = [[JMAirKissEncoder alloc] init];
        _tag             = 0;
        _returnRandomNum = 0;
        _connectionDone  = false;
        
        [self setupClientUdpSocket];
        [self setupServerUdpSocket];
    }
    return self;
}

#pragma mark - Connection
/**
 *  AirKiss连接
 *
 *  @param ssidStr ssid
 *  @param pswStr  psw
 */
- (void)connectWithSSID:(NSString *)ssidStr
               password:(NSString *)password {
    dataArray  = [_airKissEncoder createAirKissEncorderWithSSID:ssidStr ? :@""
                                                       password:password ? :@""];
    _tag                      = 0;
    _returnRandomNum          = 0;
    _connectionDone           = false;
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            _timer = [NSTimer scheduledTimerWithTimeInterval:60
                                                      target:self
                                                    selector:@selector(connectFailure)
                                                    userInfo:nil
                                                     repeats:NO];
        });
        
        [self sendCommand];
    });
}

-(void)sendCommand{
    
    if (_connectionDone == true) {
        return;
    }
    if (_tag == dataArray.count ) {
        return;
    }
    UInt16   length      = [dataArray[_tag] unsignedShortValue];
    NSMutableData *mData = [NSMutableData data];
    UInt8    value       = 0;
    for (int j = 0; j < length; j++) {
        [mData appendBytes:&value length:1];
    }
    [_clientUdpSocket sendData:mData
                        toHost:kAirKiss_Host
                          port:kAirKiss_Port
                   withTimeout:-1
                           tag:_tag];
    
    [NSThread sleepForTimeInterval:0.030];
    _tag++;
}

- (void)closeConnection {
    _connectionDone = true;
    
    [_timer invalidate];
    _timer = nil;
    
    [_clientUdpSocket close];
    [_serverUdpSocket close];
    
    _clientUdpSocket = nil;
    _serverUdpSocket = nil;
}
#pragma mark - Set up udp socket
- (void)setupClientUdpSocket
{
    NSError *error = nil;
    
    if (!_clientUdpSocket) {
        _clientUdpSocket = [[MyAirKissGCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
        [_clientUdpSocket enableBroadcast:YES error:&error];
    }
    
    if (![_clientUdpSocket bindToPort:0 error:&error])
    {
        return;
    }
    
    if (![_clientUdpSocket beginReceiving:&error])
    {
        return;
    }
}


- (void)setupServerUdpSocket {
    if (!_serverUdpSocket) {
        _serverUdpSocket = [[MyAirKissGCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
        
        NSError *error = nil;
        [_serverUdpSocket enableBroadcast:YES error:&error];
    }
    
    NSError *error = nil;
    
    if (![_serverUdpSocket bindToPort:kAirKiss_Port error:&error])
    {
        return;
    }
    
    if (![_serverUdpSocket beginReceiving:&error])
    {
        return;
    }
}


#pragma mark - Event Response
- (void)connectFailure {
    [_timer invalidate];
    _timer          = nil;
    _connectionDone = true;
    [self closeConnection];
    if (_connectionFailure) {
        _connectionFailure();
    }
}

#pragma mark - GCDAsyncUdpSocketDelegate
#pragma mark - GCDAsyncUdpSocketDelegate
- (void)udpSocket:(MyAirKissGCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag
{
    
    NSLog(@"发送数据 ：%ld",tag);
    [self sendCommand];
    
}

- (void)udpSocketDidClose:(MyAirKissGCDAsyncUdpSocket *)sock withError:(NSError *)error{
    if (_serverUdpSocket == sock) {
        NSLog(@"_serverUdpSocket关闭：%@",error);
        if(_connectionDone)
        {
            NSLog(@"_serverUdpSocket 配置已完成：%@",error);
        }else{
            NSLog(@"_clientUdpSocket 配置未完成：%@",error);
            //重新创建_serverUdpSocket ，继续接收
            NSLog(@"重新创建_serverUdpSocket ，继续接收");
            _serverUdpSocket = nil;
            [self setupServerUdpSocket];
        }
    }else if (_clientUdpSocket == sock) {
        NSLog(@"_clientUdpSocket关闭：%@",error);
        if(_connectionDone)
        {
            NSLog(@"_clientUdpSocket 配置已完成：%@",error);
        }else{
            NSLog(@"_clientUdpSocket 配置未完成：%@",error);
            //重新创建_clientUdpSocket ，继续发送
            NSLog(@"重新创建_clientUdpSocket ，继续发送");
            _clientUdpSocket = nil;
            [self setupClientUdpSocket];
            [self sendCommand];
            
        }
        
        
    }
    
}
- (void)udpSocket:(MyAirKissGCDAsyncUdpSocket *)sock didNotConnect:(NSError *)error{
    NSLog(@"连接失败 ：%@",error);
    
}

- (void)udpSocket:(MyAirKissGCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error
{
    NSLog(@"配置错误：%@",error);
}




- (void)udpSocket:(MyAirKissGCDAsyncUdpSocket *)sock
   didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
    
    
 //   NSLog(@"接收数据 ：%ld",data);
    if (_serverUdpSocket == sock) {
        if (_connectionDone) {
            return;
        }
        
        // 设备连接WIFI成功后会像10000端口发送至少20个UDP广播包所附带的随机数
        if (data != nil && data.length == 1) {
            UInt8 *bytes = (UInt8 *) [data bytes];
            if (bytes[0] == _airKissEncoder.randomChar) {
                _returnRandomNum ++;
                NSLog(@"接收到随机数：%c",_airKissEncoder.randomChar);
                
                if (_returnRandomNum >= kAirKiss_Limit_Return_Random_Num) {
                    // 成功
                    [_timer invalidate];
                    _timer = nil;
                    
                    if (_returnRandomNum == kAirKiss_Limit_Return_Random_Num) {
                        _connectionDone = true;
                        if (_connectionSuccess) {
                            [self closeConnection];
                            _connectionSuccess();
                        }
                    }
                }
            }
        }
    }
}



/**
 *  获取SSID信息
 *
 *  @return id
 */
+ (id)fetchSSIDInfo {
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    id info = nil;
    for (NSString *ifnam in ifs) {
        info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        
        if (info && [info count]) {
            break;
        }
    }
    return info;
}




@end
